package com.durian.base.frame.easyrouter;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.SparseArray;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityOptionsCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

import com.alibaba.android.arouter.core.LogisticsCenter;
import com.alibaba.android.arouter.exception.NoRouteFoundException;
import com.alibaba.android.arouter.facade.Postcard;
import com.alibaba.android.arouter.facade.callback.InterceptorCallback;
import com.alibaba.android.arouter.facade.callback.NavigationCallback;
import com.alibaba.android.arouter.facade.service.DegradeService;
import com.alibaba.android.arouter.facade.service.InterceptorService;
import com.alibaba.android.arouter.facade.service.PretreatmentService;
import com.alibaba.android.arouter.launcher.ARouter;
import com.alibaba.android.arouter.utils.TextUtils;
import com.durian.BaseApp;

import java.io.Serializable;
import java.util.ArrayList;


/**
 * 说明：EasyRouter路由器
 * <p/>
 * 作者：fanly
 * <p/>
 * 类型：Class
 * <p/>
 * 时间：2018/6/2 17:20
 * <p/>
 * 版本：version 1.0
 */
public final class EasyRouter {

    public static final String KEY_EXTRA = "KEY_EXTRA";
    public static final String KEY_FRAGMENT = "KEY_FRAGMENT";
    public static final String PATH_BIND_FRAGMENT = "/bind/fragment";

    private static final String                 TAG_ACTIVITY_RESULT_FRAGMENT = "EasyRouter";
    public static final int                    EASY_REQUEST_CODE            = 2020;
    private              Postcard               mPostcard;

    private static OnJumpListener jumpListener;
    private static InterceptorService interceptorService;
    private static void initInterceptorService(){
        // Trigger interceptor init, use byName.
        interceptorService = (InterceptorService) ARouter.getInstance().build("/arouter/service/interceptor").navigation();
    }

    public static void setOnJumpListener(OnJumpListener listener){
        jumpListener = listener;
    }

    private EasyRouter(String path) {
        mPostcard = ARouter.getInstance().build(path);
    }


    private EasyRouter(Uri uri) {
        mPostcard = ARouter.getInstance().build(uri);
    }

    /**
     * Build the roadmap, draw a postcard.
     *
     * @param path Where you go.
     */
    public static EasyRouter build(String path) {
        EasyRouter router;
        int index = path == null ? -1 : path.indexOf('?');
        if (index > 0){
            String []plist = path.split("\\?");
            if (plist != null && plist.length == 2 && !TextUtils.isEmpty(plist[1]) && !TextUtils.isEmpty(plist[0])){
                router = new EasyRouter(plist[0]);
                String []extras = plist[1].split("&");
                if (extras != null && extras.length > 0){
                    for (String ext:extras){
                        if (!TextUtils.isEmpty(ext)){
                            String []params = ext.split("=");
                            if (params != null && params.length == 2 && !TextUtils.isEmpty(params[0]) && !TextUtils.isEmpty(params[1])){
                                router.withString(params[0],params[1]);
                            }
                        }
                    }
                }
            }else {
                router = new EasyRouter(path);
            }
        }else {
            router = new EasyRouter(path);
        }
        return router;
    }


    /**
     * Build the roadmap, draw a postcard.
     *
     * @param uri the path
     */
    public static EasyRouter build(Uri uri) {
        EasyRouter router = new EasyRouter(uri);
        return router;
    }

    /**
     * Build by fragment,this fragment must extends fragmentbind
     * @return
     */
    public static EasyRouter buildByFragment(String fragmentPath){
        EasyRouter router = new EasyRouter(PATH_BIND_FRAGMENT);
        router.withString(KEY_FRAGMENT,fragmentPath);
        return router;
    }

    /**
     * Build by fragment,this fragment must extends fragmentbind
     * @return
     */
    public static EasyRouter buildByFragment(String fragmentPath,String activityPath){
        EasyRouter router = new EasyRouter(activityPath);
        router.withString(KEY_FRAGMENT,fragmentPath);
        return router;
    }

    public Postcard getPostcard(){
        return mPostcard;
    }

    public static void inject(Object object){
        ARouter.getInstance().inject(object);
    }

    public EasyRouter setTag(Object tag) {
        if (mPostcard != null) {
            mPostcard.setTag(tag);
        }
        return this;
    }

    /**
     * Set Router Extra
     * @param extra
     * @return
     */
    public EasyRouter setExtra(int extra){
        return withInt(KEY_EXTRA,extra);
    }

    /**
     * Get Router Extra
     * @return
     */
    public int getExtra(){
        return getExtra(mPostcard);
    }

    /**
     * Get Router Extra
     * @param postcard
     * @return
     */
    public static int getExtra(Postcard postcard){
        Bundle bundle = postcard.getExtras();
        int extra = bundle.getInt(KEY_EXTRA,Integer.MIN_VALUE);
        if (extra == Integer.MIN_VALUE){
            return postcard.getExtra();
        }else {
            return extra;
        }
    }

    /**
     * Set timeout of navigation this time.
     *
     * @param timeout timeout
     * @return this
     */
    public EasyRouter setTimeout(int timeout) {
        if (mPostcard != null) {
            mPostcard.setTimeout(timeout);
        }
        return this;
    }

    public EasyRouter setUri(Uri uri) {
        if (mPostcard != null) {
            mPostcard.setUri(uri);
        }
        return this;
    }

    /**
     * Navigation to the route with path in postcard.
     * No param, will be use application context.
     */
    public Object navigation() {
        return navigation(null);
    }

    /**
     * Navigation to the route with path in postcard.
     *
     * @param context Activity and so on.
     */
    public Object navigation(Context context) {
        return navigation(context, null);
    }

    /**
     * Navigation to the route with path in postcard.
     *
     * @param context Activity and so on.
     */
    public Object navigation(Context context, NavigationCallback callback) {
        if (mPostcard != null) {
            if (jumpListener != null){
                jumpListener.jumpActivity(mPostcard.getExtras());
            }
            return ARouter.getInstance().navigation(context, mPostcard, -1, callback);
        } else {
            return null;
        }
    }

    public void navigation(Activity activity,int requestCode){
        if (mPostcard != null && activity != null){
            if (jumpListener != null){
                jumpListener.jumpActivity(mPostcard.getExtras());
            }
            mPostcard.navigation(activity,requestCode);
        }
    }

    public void navigation(Activity activity,int requestCode,NavigationCallback callback){
        if (mPostcard != null && activity != null){
            if (jumpListener != null){
                jumpListener.jumpActivity(mPostcard.getExtras());
            }
            mPostcard.navigation(activity,requestCode,callback);
        }
    }

    public void navigation(Activity activity, OnActivityResultListener listener) {
        navigation(activity,listener,null);
    }

    public void navigation(Activity activity, OnActivityResultListener listener,NavigationCallback callback) {
        BaseApp.runInMainThread(new Runnable() {
            @Override
            public void run() {
                if (listener == null) {
                    navigation(activity, callback);
                }else {
                    ActivityResultFragment fragment = getActivityResultFragment(activity);
                    if (fragment != null){
                        navigationForActivityResult(fragment,listener,callback);
                    }else {
                        navigation(activity,callback);
                    }
                }
            }
        });
    }

    private void navigationForActivityResult(ActivityResultFragment fragment,OnActivityResultListener listener,NavigationCallback callback){
        PretreatmentService pretreatmentService = ARouter.getInstance().navigation(PretreatmentService.class);
        if (null != pretreatmentService && !pretreatmentService.onPretreatment(fragment.getContext(), mPostcard)) {
            return;
        }

        try {
            LogisticsCenter.completion(mPostcard);
        } catch (NoRouteFoundException ex) {

            if (ARouter.debuggable()) {
                // Show friendly tips for user.
                BaseApp.runInMainThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(fragment.getActivity(), "There's no route matched!\n" +
                                " Path = [" + mPostcard.getPath() + "]\n" +
                                " Group = [" + mPostcard.getGroup() + "]", Toast.LENGTH_LONG).show();
                    }
                });
            }

            if (null != callback) {
                callback.onLost(mPostcard);
            } else {
                // No callback for this invoke, then we use the global degrade service.
                DegradeService degradeService = ARouter.getInstance().navigation(DegradeService.class);
                if (null != degradeService) {
                    degradeService.onLost(fragment.getActivity(), mPostcard);
                }
            }
            return;
        }

        if (null != callback) {
            callback.onFound(mPostcard);
        }
        initInterceptorService();
        if (interceptorService != null){
            if (!mPostcard.isGreenChannel()) {   // It must be run in async thread, maybe interceptor cost too mush time made ANR.
                interceptorService.doInterceptions(mPostcard, new InterceptorCallback() {
                    /**
                     * Continue process
                     *
                     * @param postcard route meta
                     */
                    @Override
                    public void onContinue(Postcard postcard) {
                        _navigationForActivityResult(fragment,listener,callback);
                    }

                    /**
                     * Interrupt process, pipeline will be destory when this method called.
                     *
                     * @param exception Reson of interrupt.
                     */
                    @Override
                    public void onInterrupt(Throwable exception) {
                        if (null != callback) {
                            callback.onInterrupt(mPostcard);
                        }
                    }
                });
            } else {
                _navigationForActivityResult(fragment,listener,callback);
            }
        }else {
            _navigationForActivityResult(fragment,listener,callback);
        }
    }

    private void _navigationForActivityResult(ActivityResultFragment fragment,OnActivityResultListener listener,NavigationCallback callback){
        if (jumpListener != null){
            jumpListener.jumpActivity(mPostcard.getExtras());
        }
        // Build intent
        final Intent intent = new Intent(fragment.getActivity(), mPostcard.getDestination());
        intent.putExtras(mPostcard.getExtras());

        // Set flags.
        int flags = mPostcard.getFlags();
        if (-1 != flags) {
            intent.setFlags(flags);
        }

        // Set Actions
        String action = mPostcard.getAction();
        if (!TextUtils.isEmpty(action)) {
            intent.setAction(action);
        }

        // Navigation in main looper.
        fragment.setActivityResultListener(listener);
        fragment.startActivityForResult(intent,EASY_REQUEST_CODE,mPostcard.getOptionsBundle());

        if ((-1 != mPostcard.getEnterAnim() && -1 != mPostcard.getExitAnim())) {    // Old version.
            (fragment.getActivity()).overridePendingTransition(mPostcard.getEnterAnim(), mPostcard.getExitAnim());
        }

        if (null != callback) { // Navigation over.
            callback.onArrival(mPostcard);
        }
    }

    /**
     * Green channel, it will skip all of interceptors.
     *
     * @return this
     */
    public EasyRouter greenChannel() {
        if (mPostcard != null) {
            mPostcard.greenChannel();
        }
        return this;
    }

    public EasyRouter withAll(Bundle bundle){
        if (mPostcard != null){
            if (mPostcard.getExtras() == null){
                mPostcard.with(bundle);
            }else {
                mPostcard.getExtras().putAll(bundle);
            }
        }
        return this;
    }

    /**
     * Set special flags controlling how this intent is handled.  Most values
     * here depend on the type of component being executed by the Intent,
     * specifically the FLAG_ACTIVITY_* flags are all for use with
     * {@link Context#startActivity Context.startActivity()} and the
     * FLAG_RECEIVER_* flags are all for use with
     * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}.
     */
    public EasyRouter withFlags(int flag) {
        if (mPostcard != null) {
            mPostcard.withFlags(flag);
        }
        return this;
    }

    /**
     * Add additional flags to the intent (or with existing flags
     * value).
     *
     * @param flags The new flags to set.
     * @return Returns the same Intent object, for chaining multiple calls
     * into a single statement.
     * @see #withFlags
     */
    public EasyRouter addFlags(int flags) {
        if (mPostcard != null) {
            mPostcard.addFlags(flags);
        }
        return this;
    }

    /**
     * Set object value, the value will be convert to string by 'Fastjson'
     *
     * @param key a String, or null
     * @param value a Object, or null
     * @return current
     */
    public EasyRouter withObject(@Nullable String key, @Nullable Object value) {
        if (mPostcard != null) {
            mPostcard.withObject(key, value);
        }
        return this;
    }

    // Follow api copy from #{Bundle}

    /**
     * Inserts a String value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a String, or null
     * @return current
     */
    public EasyRouter withString(@Nullable String key, @Nullable String value) {
        if (mPostcard != null) {
            mPostcard.withString(key, value);
        }
        return this;
    }

    /**
     * Inserts a Boolean value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a boolean
     * @return current
     */
    public EasyRouter withBoolean(@Nullable String key, boolean value) {
        if (mPostcard != null) {
            mPostcard.withBoolean(key, value);
        }
        return this;
    }

    /**
     * Inserts a short value into the mapping of this Bundle, replacing
     * any existing value for the given key.
     *
     * @param key a String, or null
     * @param value a short
     * @return current
     */
    public EasyRouter withShort(@Nullable String key, short value) {
        if (mPostcard != null) {
            mPostcard.withShort(key, value);
        }
        return this;
    }

    /**
     * Inserts an int value into the mapping of this Bundle, replacing
     * any existing value for the given key.
     *
     * @param key a String, or null
     * @param value an int
     * @return current
     */
    public EasyRouter withInt(@Nullable String key, int value) {
        if (mPostcard != null) {
            mPostcard.withInt(key, value);
        }
        return this;
    }

    /**
     * Inserts a long value into the mapping of this Bundle, replacing
     * any existing value for the given key.
     *
     * @param key a String, or null
     * @param value a long
     * @return current
     */
    public EasyRouter withLong(@Nullable String key, long value) {
        if (mPostcard != null) {
            mPostcard.withLong(key, value);
        }
        return this;
    }

    /**
     * Inserts a double value into the mapping of this Bundle, replacing
     * any existing value for the given key.
     *
     * @param key a String, or null
     * @param value a double
     * @return current
     */
    public EasyRouter withDouble(@Nullable String key, double value) {
        if (mPostcard != null) {
            mPostcard.withDouble(key, value);
        }
        return this;
    }

    /**
     * Inserts a byte value into the mapping of this Bundle, replacing
     * any existing value for the given key.
     *
     * @param key a String, or null
     * @param value a byte
     * @return current
     */
    public EasyRouter withByte(@Nullable String key, byte value) {
        if (mPostcard != null) {
            mPostcard.withByte(key, value);
        }
        return this;
    }

    /**
     * Inserts a char value into the mapping of this Bundle, replacing
     * any existing value for the given key.
     *
     * @param key a String, or null
     * @param value a char
     * @return current
     */
    public EasyRouter withChar(@Nullable String key, char value) {
        if (mPostcard != null) {
            mPostcard.withChar(key, value);
        }
        return this;
    }

    /**
     * Inserts a float value into the mapping of this Bundle, replacing
     * any existing value for the given key.
     *
     * @param key a String, or null
     * @param value a float
     * @return current
     */
    public EasyRouter withFloat(@Nullable String key, float value) {
        if (mPostcard != null) {
            mPostcard.withFloat(key, value);
        }
        return this;
    }

    /**
     * Inserts a CharSequence value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a CharSequence, or null
     * @return current
     */
    public EasyRouter withCharSequence(@Nullable String key, @Nullable CharSequence value) {
        if (mPostcard != null) {
            mPostcard.withCharSequence(key, value);
        }
        return this;
    }

    /**
     * Inserts a Parcelable value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a Parcelable object, or null
     * @return current
     */
    public EasyRouter withParcelable(@Nullable String key, @Nullable Parcelable value) {
        if (mPostcard != null) {
            mPostcard.withParcelable(key, value);
        }
        return this;
    }

    /**
     * Inserts an array of Parcelable values into the mapping of this Bundle,
     * replacing any existing value for the given key.  Either key or value may
     * be null.
     *
     * @param key a String, or null
     * @param value an array of Parcelable objects, or null
     * @return current
     */
    public EasyRouter withParcelableArray(@Nullable String key, @Nullable Parcelable[] value) {
        if (mPostcard != null) {
            mPostcard.withParcelableArray(key, value);
        }
        return this;
    }

    /**
     * Inserts a List of Parcelable values into the mapping of this Bundle,
     * replacing any existing value for the given key.  Either key or value may
     * be null.
     *
     * @param key a String, or null
     * @param value an ArrayList of Parcelable objects, or null
     * @return current
     */
    public EasyRouter withParcelableArrayList(@Nullable String key, @Nullable ArrayList<? extends Parcelable> value) {
        if (mPostcard != null) {
            mPostcard.withParcelableArrayList(key, value);
        }
        return this;
    }

    /**
     * Inserts a SparceArray of Parcelable values into the mapping of this
     * Bundle, replacing any existing value for the given key.  Either key
     * or value may be null.
     *
     * @param key a String, or null
     * @param value a SparseArray of Parcelable objects, or null
     * @return current
     */
    public EasyRouter withSparseParcelableArray(@Nullable String key, @Nullable SparseArray<? extends Parcelable> value) {
        if (mPostcard != null) {
            mPostcard.withSparseParcelableArray(key, value);
        }
        return this;
    }

    /**
     * Inserts an ArrayList value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value an ArrayList object, or null
     * @return current
     */
    public EasyRouter withIntegerArrayList(@Nullable String key, @Nullable ArrayList<Integer> value) {
        if (mPostcard != null) {
            mPostcard.withIntegerArrayList(key, value);
        }
        return this;
    }

    /**
     * Inserts an ArrayList value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value an ArrayList object, or null
     * @return current
     */
    public EasyRouter withStringArrayList(@Nullable String key, @Nullable ArrayList<String> value) {
        if (mPostcard != null) {
            mPostcard.withStringArrayList(key, value);
        }
        return this;
    }

    /**
     * Inserts an ArrayList value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value an ArrayList object, or null
     * @return current
     */
    public EasyRouter withCharSequenceArrayList(@Nullable String key, @Nullable ArrayList<CharSequence> value) {
        if (mPostcard != null) {
            mPostcard.withCharSequenceArrayList(key, value);
        }
        return this;
    }

    /**
     * Inserts a Serializable value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a Serializable object, or null
     * @return current
     */
    public EasyRouter withSerializable(@Nullable String key, @Nullable Serializable value) {
        if (mPostcard != null) {
            mPostcard.withSerializable(key, value);
        }
        return this;
    }

    /**
     * Inserts a byte array value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a byte array object, or null
     * @return current
     */
    public EasyRouter withByteArray(@Nullable String key, @Nullable byte[] value) {
        if (mPostcard != null) {
            mPostcard.withByteArray(key, value);
        }
        return this;
    }

    /**
     * Inserts a short array value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a short array object, or null
     * @return current
     */
    public EasyRouter withShortArray(@Nullable String key, @Nullable short[] value) {
        if (mPostcard != null) {
            mPostcard.withShortArray(key, value);
        }
        return this;
    }

    /**
     * Inserts a char array value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a char array object, or null
     * @return current
     */
    public EasyRouter withCharArray(@Nullable String key, @Nullable char[] value) {
        if (mPostcard != null) {
            mPostcard.withCharArray(key, value);
        }
        return this;
    }

    /**
     * Inserts a float array value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a float array object, or null
     * @return current
     */
    public EasyRouter withFloatArray(@Nullable String key, @Nullable float[] value) {
        if (mPostcard != null) {
            mPostcard.withFloatArray(key, value);
        }
        return this;
    }

    /**
     * Inserts a CharSequence array value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a CharSequence array object, or null
     * @return current
     */
    public EasyRouter withCharSequenceArray(@Nullable String key, @Nullable CharSequence[] value) {
        if (mPostcard != null) {
            mPostcard.withCharSequenceArray(key, value);
        }
        return this;
    }

    /**
     * Inserts a Bundle value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a Bundle object, or null
     * @return current
     */
    public EasyRouter withBundle(@Nullable String key, @Nullable Bundle value) {
        if (mPostcard != null) {
            mPostcard.withBundle(key, value);
        }
        return this;
    }

    /**
     * Set normal transition anim
     *
     * @param enterAnim enter
     * @param exitAnim exit
     * @return current
     */
    public EasyRouter withTransition(int enterAnim, int exitAnim) {
        if (mPostcard != null) {
            mPostcard.withTransition(enterAnim, exitAnim);
        }
        return this;
    }

    /**
     * Set options compat
     *
     * @param compat compat
     * @return this
     */
    @RequiresApi(16)
    public EasyRouter withOptionsCompat(ActivityOptionsCompat compat) {
        if (mPostcard != null) {
            mPostcard.withOptionsCompat(compat);
        }
        return this;
    }

    public EasyRouter withAction(String action) {
        if (mPostcard != null) {
            mPostcard.withAction(action);
        }
        return this;
    }

    @Override
    public String toString() {
        if (mPostcard != null) {
            return mPostcard.toString();
        }
        return super.toString();
    }

    private Fragment findActivityResultFragment(FragmentActivity activity) {
        return activity.getSupportFragmentManager().findFragmentByTag(TAG_ACTIVITY_RESULT_FRAGMENT);
    }

    private ActivityResultFragment getActivityResultFragment(Activity activity) {
        if (activity instanceof FragmentActivity) {
            FragmentActivity fragmentActivity = (FragmentActivity) activity;
            Fragment activityResultFragment = findActivityResultFragment(fragmentActivity);
            if (activityResultFragment == null) {
                FragmentManager fragmentManager = fragmentActivity.getSupportFragmentManager();
                if (fragmentManager.isDestroyed()){
                    return null;
                }
                activityResultFragment = new ActivityResultFragment();
                fragmentManager.beginTransaction().add(activityResultFragment, TAG_ACTIVITY_RESULT_FRAGMENT).commitAllowingStateLoss();
                fragmentManager.executePendingTransactions();
            }
            return (ActivityResultFragment) activityResultFragment;
        } else {
            return null;
        }
    }

    public static void jumpActivity(Context context,Class<? extends Activity> cls,Bundle bundle){
        if (context == null || cls == null){
            return;
        }
        Intent intent = new Intent(context,cls);
        if (context instanceof Application){
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        if (bundle != null){
            intent.putExtras(bundle);
        }
        context.startActivity(intent);
    }

    public static void skipActivity(Activity activity,Class<? extends Activity> cls,Bundle bundle){
        if (activity == null || cls == null){
            return;
        }
        jumpActivity(activity,cls,bundle);
        activity.finish();
    }

    public static void jumpActivity(Context context,Class<? extends Activity> cls){
        jumpActivity(context,cls,null);
    }

    public static void skipActivity(Activity activity,Class<? extends Activity> cls){
        skipActivity(activity,cls,null);
    }

    public static void jumpActivity(Class<? extends Activity> cls){
        jumpActivity(BaseApp.getApp(),cls,null);
    }


}
